#include "LynxWinFunc.h"
#include "RenderUtils.h"
#include "Lynx6.h"
//
//float ambientColor[]= {0.3f, 0.3f, 0.3f, 1 };

//for testing purposes
vector<float> Params(5+3);
CvCapture* myVideoCapture;

LynxWinFunc::LynxWinFunc(int w, int h, int numWin)
{
	Params[5] = 19.9;
	Params[6] = 11.9;
	Params[7] = 124.6;

	screenH = h; 
	screenW = w;

	cvNamedWindow("VideoIn");
	cvResizeWindow("VideoIn",w,h);
	cvMoveWindow("VideoIn",w+20,1);
	
	this->steps = 0;
	this->dt = 0.025;
	this->numWindows = numWin;
	this->cams.SetNumCams(numWindows);
	this->bReadNextFrame = false;
	Init();
}

void LynxWinFunc::IdleCallback() {

	// perform updates here!
	DisplayCallback();
}

void LynxWinFunc::Init()
{   
	// this is a piece of crap apparently, can't load many things...
	/*myVideoCapture = cvCreateFileCapture( "../data/Movie4.avi" );
	if( !myVideoCapture ) {
		cout<<"Error reading movie file, are you sure the file exists?\n";
		cout<<"Also it is possible that the openCV codecs can't read it.\n";
	}*/
	for( int i = 0; i < this->numWindows; i++ ) {
		if( numWindows > 1 )
			glutSetWindow(i+1);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glClearColor(0.0, 0.0 , 0.0, 0.0 );
		glShadeModel(GL_FLAT);
		glEnable(GL_DEPTH_TEST);
		glClear( GL_COLOR_BUFFER_BIT );
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);
		glEnable(GL_LIGHT1);
		glEnable(GL_NORMALIZE);
		glEnable(GL_COLOR_MATERIAL);
	}
	if( numWindows > 1 )
		glutSetWindow(1);

	this->cams.InitCamsUniform(screenW, screenH);
	this->currentWindowID = 1;
}

LynxWinFunc::~LynxWinFunc()
{
	// delete any pointers here
}

void LynxWinFunc::Reset() {
	// add any additional reset code here
	Init();
}

// x & y are current mouse cursor coordinates
// x = 1, y = 1 is the upper left cornder of the window
void LynxWinFunc::KeyboardCallback(unsigned char key, int x, int y)
{	
	if( key == 'R' ) {
		cout<<"Resetting... \n";
		this->Reset();
	}

	if( key == 'i' ) {
		cout<<"testing openCV...";
		IplImage* img = cvCreateImage( cvSize(300,300), IPL_DEPTH_8U, 3 );
		cvSaveImage( "test_img.png", img);
		cout<<" test_img.png has been saved! \n";
	}
	if( key == 't' ) {
		cout<<"opengl render readback and save...\n";
		//TestReadBuffer(this->screenH, this->screenW);
		SaveAllBuffers(screenW, screenH, numWindows);
	}
	if (27 == key)
	{
		exit(0);

	}
	vector<float> curAngs;
	GetParams(curAngs);
	if( key == 'a' ) {
		Params[0] = curAngs[0] - 0.5;
	}
	if( key == 'A' ) {
		Params[0] = curAngs[0] + 0.5;
	}
	if( key == 's' ) {
		Params[1] = curAngs[1] - 0.5;
	}
	if( key == 'S' ) {
		Params[1] = curAngs[1] + 0.5;
	}
	if( key == 'd' ) {
		Params[2] = curAngs[2] - 0.5;
	}
	if( key == 'D' ) {
		Params[2] = curAngs[2] + 0.5;
	}
	if( key == 'f' ) {
		Params[3] = curAngs[3] - 0.5;
	}
	if( key == 'F' ) {
		Params[3] = curAngs[3] + 0.5;
	}
	if( key == 'g' ) {
		Params[4] = curAngs[4] - 0.5;
	}
	if( key == 'G' ) {
		Params[4] = curAngs[4] + 0.5;
	}
	if( key == 'q' ) {
		Params[5] = curAngs[5] - 0.1;
	}
	if( key == 'Q' ) {
		Params[5] = curAngs[5] + 0.1;
	}
	if( key == 'w' ) {
		Params[6] = curAngs[6] - 0.1;
	}
	if( key == 'W' ) {
		Params[6] = curAngs[6] + 0.1;
	}
	if( key == 'e' ) {
		Params[7] = curAngs[7] - 0.125;
	}
	if( key == 'E' ) {
		Params[7] = curAngs[7] + 0.125;
	}

	if( key == 'H' ) {
		this->bReadNextFrame = true;
	}
	if( key == 'h' ) {
		this->bReadNextFrame = false;
	}

}

#define BUFSIZE 512;
void LynxWinFunc::MouseCallback(int button, int state, int x, int y)
{ 
   // use mouse click picking ? see old code somewhere for reference	
}

void LynxWinFunc::DisplayCallback()
{
	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH_TEST);
	glClear( GL_COLOR_BUFFER_BIT );


	int idx = 0; 
	if( numWindows > 1 ) {
		idx = glutGetWindow()-1;
		glutSetWindow( currentWindowID ); // force-set it so clicking doens't change focus
	}
	cams.ModelView(currentWindowID-1); // Set CamView
	

	PassParams(Params );
	drawArm();
	
	if( 1 == currentWindowID  && this->bReadNextFrame) {
		steps++;
		
		// don't use this for now anyway, it is buggy
		//int result = cvGrabFrame( myVideoCapture );
		//Note: the doc says "Do not release this pointer by user..."
		//IplImage* imgin = cvQueryFrame( myVideoCapture );
				
		IplImage* imgin = ReadImgByNum("../../../data/arm1png/",".png",steps,8);
		cvShowImage( "VideoIn", imgin );
		cvWaitKey(1);
		cvReleaseImage(&imgin);
		if( steps == 330 )
			steps = 0;
		this->bReadNextFrame = false;
	}
	glFinish();
	glutSwapBuffers();

	currentWindowID = currentWindowID % numWindows + 1;
	if( numWindows > 1 )
		glutSetWindow( currentWindowID );
}

void LynxWinFunc::ResizeCallback(int w, int h)
{
	screenH = h;
	screenW = w;
	
	int idx = 0;
	if( numWindows > 1 )
		idx = glutGetWindow()-1;
	cams.ResizeCallbackOne(w,h,idx);
}


